﻿using System.Collections.Generic;
using Zove.DesignTime;
using Zove.Runtime;
using System.Diagnostics;
using System;

namespace CommonModellingRuntime.Ascend {

    /// <summary>
    /// The Ascend model, first load, then run and finally run the self test.
    /// </summary>
    public class AscendModel {

        public string Source {
            get;
            private set;
        }

        public Dictionary<string, string> Load {
            get;
            private set;
        }

        public List<ZoomEquation> Body {
            get;
            private set;
        }

        public List<string> SelfAssert {
            get;
            private set;
        }

        private ModelInstance instance = null;

        public AscendModel() { }

        public AscendModel(string source)
            : base() {
            this.Source = source;

            Load = new Dictionary<string, string>();

            instance = new ModelInstance();

            DefaultRuntimeModelLoader loader = new DefaultRuntimeModelLoader();
            loader.ClassLoader = new AscendClassLoader();

            instance.Model = loader.LoadBySource(this.Source);
        }

        /// <summary>
        /// Load and run the equatoins.
        /// </summary>
        public void Run() {
            foreach (string key in Load.Keys) {
                instance.Initialize(key, Load[key]);
            }

            instance.Evaluate();
        }

        public void SelfTest() {
            foreach (string assertion in SelfAssert) {
                object obj = instance.Evaluate(assertion);
                Debug.Assert(obj != null, "The expression returns null");
                Debug.Assert(Convert.ToBoolean(obj), "The expression is false");
            }
        }

        public override string ToString() {
            return instance.Model.ToString();
        }
    }
}
